// 公共方法
const crypto = require('crypto')
const log4js = require('../utils/log4')
const logger = log4js.getLogger('server/router_handler/material.js')
const { v4: uuidv4 } = require('uuid')

/** 获取当前时间戳 */
exports.getNowTime = () => {
  // 获取当前时间的毫秒级时间戳
  const timestampInMillis = new Date().getTime()
  // 将毫秒级时间戳除以1000并取整，得到10位时间戳
  return Math.floor(timestampInMillis / 1000)
}

/** 时间格式化 */
exports.formatTimestamp = timestamp => {
  // 将时间戳拆分为年、月、日、时、分和秒
  const dt = new Date(timestamp * 1000)
  const y = dt.getFullYear()
  const m = (dt.getMonth() + 1 + '').padStart(2, '0')
  const d = (dt.getDate() + '').padStart(2, '0')

  const hh = (dt.getHours() + '').padStart(2, '0')
  const mm = (dt.getMinutes() + '').padStart(2, '0')
  const ss = (dt.getSeconds() + '').padStart(2, '0')
  // yyyy-mm-dd hh:mm:ss
  return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}

/**
 * 获取当天的最早时刻（00:00:00）和最晚时刻（23:59:59)
 * @param {*} dateString 字符串 如：'2024-2-29'
 * @returns  startOfDay, endOfDay: 最早时刻和最晚时刻的时间戳 Date类型
 */
exports.getDateRange = dateString => {
  const date = new Date(dateString)

  // 获取当天的最早时刻
  const startOfDay = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1, 0, 0, 0)

  // 获取当天的最晚时刻
  const endOfDay = new Date(date.getFullYear(), date.getMonth() , date.getDate(), 23, 59, 59)

  return { startOfDay, endOfDay }
}

/** 生产唯一code */
exports.generateUniqueCode = () => {
  const data = uuidv4()
  const hash = crypto.createHash('MD5')
  hash.update(data)
  return hash.digest('hex')
}

/**生成给定范围的随机整数*/
exports.generateRandomInteger = (min, max) => {
  return Math.floor(Math.random() * (max - min + 1)) + min
}

/**
 * 返回数组中的随机一个元素
 * @param {*} array 数组
 * @returns
 */
exports.getRandomElement = array => {
  return array[Math.floor(Math.random() * array.length)]
}

/**
 * 按照素材类型生产对于训练参数
 * @param {Number} industryType
 * @returns
 */
exports.generateTrainingParams = industryType => {
  let params = {}

  switch (industryType) {
    case 7:
      params = {
        最大速度限制: Math.floor(Math.random() * 80 + 40) + '公里/小时',
        交通拥堵系数: parseFloat((Math.random() * (0.7 - 0.3) + 0.3).toFixed(2)),
        道路条件评分: Math.random() > 0.3 ? '良好' : Math.random() > 0.5 ? '一般' : '恶劣',
        交通信号灯等待时间: Math.floor(Math.random() * 60 + 30) + '秒',
        车辆载重量: Math.floor(Math.random() * 30 + 10) + '吨',
        货物类型: Math.random() > 0.5 ? '普通货物' : '易碎品'
      }
      break
    case 5:
      params = {
        特征选择: ['交易金额', '交易地点', '交易时间', '交易频率', '客户年龄', '保单金额'],
        模型类型: Math.random() > 0.5 ? '逻辑回归' : '决策树',
        阈值设定: parseFloat((Math.random() * (0.7 - 0.3) + 0.3).toFixed(2)),
        数据采样方法: Math.random() > 0.5 ? '过采样' : '欠采样',
        保险类型: Math.random() > 0.5 ? '车险' : '人寿险'
      }
      break
    case 9:
      params = {
        气象数据: ['温度', '湿度', '降雨量', '风速'],
        土壤含水量: Math.floor(Math.random() * 50 + 30) + '%',
        种植面积: Math.floor(Math.random() * 500 + 200) + '亩',
        作物品种: Math.random() > 0.5 ? '小麦' : '玉米',
        农药种类: Math.random() > 0.5 ? '杀虫剂' : '除草剂'
      }
      break
    case 12:
      params = {
        传感器数据采集频率: '每秒' + (Math.floor(Math.random() * 5) + 1) + '次',
        异常检测阈值: parseFloat((Math.random() * (0.3 - 0.1) + 0.1).toFixed(2)),
        生产线速度: '每小时' + Math.floor(Math.random() * 150 + 50) + '件',
        生产温度: '摄氏度' + Math.floor(Math.random() * 20 + 20) + '度',
        生产压力: Math.floor(Math.random() * 20 + 10) + 'Mpa',
        产品类型: Math.random() > 0.5 ? '家电' : '汽车零部件'
      }
      break
    case 1:
      params = {
        分子特征提取方法: Math.random() > 0.5 ? '指纹编码' : '神经网络',
        化学键类型: Math.random() > 0.5 ? ['碳-氢键', '氧-氢键'] : ['氮-氢键', '硫-氢键'],
        原子数量: Math.floor(Math.random() * 40 + 10) + '个',
        分子量: Math.floor(Math.random() * 300 + 100) + '克/摩尔',
        药物剂型: Math.random() > 0.5 ? '片剂' : '注射液',
        适应症: Math.random() > 0.5 ? '感冒' : '发烧'
      }
      break
    case 11:
      params = {
        用户历史观影记录:
          Math.random() > 0.5
            ? ['用户A观看了《阿凡达》', '用户B观看了《星球大战》']
            : ['用户C观看了《变形金刚》', '用户D观看了《速度与激情》'],
        电影类型: Math.random() > 0.5 ? ['科幻', '动作'] : ['喜剧', '爱情'],
        评分数据: Math.random() > 0.5 ? 'IMDb评分' : '豆瓣评分',
        时间偏好: Math.random() > 0.5 ? '晚上7点到9点' : '下午3点到5点',
        观影地点: Math.random() > 0.5 ? '电影院' : '家里'
      }
      break
    case 6:
      params = {
        目标市场: Math.random() > 0.5 ? 'B2B' : 'B2C',
        广告渠道: Math.random() > 0.5 ? ['社交媒体', '搜索引擎'] : ['电视广告', '广播'],
        推广活动: Math.random() > 0.5 ? '折扣促销' : '新品发布',
        受众定位: Math.random() > 0.5 ? '年龄段' : '兴趣爱好',
        销售周期: Math.floor(Math.random() * 90 + 30) + '天'
      }
      break
    case 10:
      params = {
        课程类型: Math.random() > 0.5 ? '在线课程' : '传统课堂',
        学科领域: Math.random() > 0.5 ? ['数学', '科学'] : ['语言', '历史'],
        教学方法: Math.random() > 0.5 ? '探究式学习' : '讲授式教学',
        学生年龄: Math.floor(Math.random() * 6 + 6) + '岁',
        课程难度: Math.random() > 0.5 ? '初级' : '高级'
      }
      break
    case 2:
      params = {
        设备类型: Math.random() > 0.5 ? '车床' : '铣床',
        加工材料: Math.random() > 0.5 ? '金属' : '塑料',
        加工精度要求: Math.random() > 0.5 ? '精密加工' : '普通加工',
        加工速度: Math.floor(Math.random() * 1000 + 500) + 'mm/s',
        工件尺寸: Math.floor(Math.random() * 500 + 100) + 'mm'
      }
      break
    case 8:
      params = {
        能源类型: Math.random() > 0.5 ? '煤炭' : '天然气',
        能源消耗量: Math.floor(Math.random() * 5000 + 1000) + '吨',
        能源价格: parseFloat((Math.random() * (5 - 2) + 2).toFixed(2)) + '元/吨',
        能源供应商: Math.random() > 0.5 ? '国有企业' : '私营企业',
        能源用途: Math.random() > 0.5 ? '发电' : '加热'
      }
      break
    case 3:
      params = {
        贷款利率: parseFloat((Math.random() * (10 - 5) + 5).toFixed(2)) + '%',
        股票代码: Math.random() > 0.5 ? 'AAPL' : 'GOOG',
        利润率: parseFloat((Math.random() * (20 - 10) + 10).toFixed(2)) + '%',
        财务指标: Math.random() > 0.5 ? '市盈率' : '市净率',
        贷款期限: Math.floor(Math.random() * 10 + 5) + '年'
      }
      break
    case 4:
      params = {
        个人信用记录: parseFloat((Math.random() * (800 - 500) + 500).toFixed(2)),
        收入水平: Math.floor(Math.random() * 100000 + 20000) + '元/月',
        负债情况: Math.floor(Math.random() * 100000 + 20000) + '元',
        贷款用途: Math.random() > 0.5 ? '购房' : '购车'
      }
      break
    // 可以继续添加其他行业的参数生成逻辑
    default:
      params = {}
      break
  }

  return params
}

// 生成随机的公司名称
exports.generateCompanyName = () => {
  const prefixes = ['信和', '百利', '华鼎', '鼎力', '泰和', '和昌', '嘉盛', '盛华', '富邦', '鸿运']
  const middles = ['科技', '信息', '创新', '科学', '实验', '工程', '研发', '网络', '智能', '数字']
  const suffixes = [
    '有限公司',
    '科技有限公司',
    '网络有限公司',
    '信息科技有限公司',
    '集团',
    '电子商务公司',
    '软件工程公司',
    '科技股份有限公司',
    '信息科技股份有限公司'
  ]

  const prefix = prefixes[Math.floor(Math.random() * prefixes.length)]
  const middle = middles[Math.floor(Math.random() * middles.length)]
  const suffix = suffixes[Math.floor(Math.random() * suffixes.length)]

  // 拼接生成的公司名称
  return `${prefix}${middle}${suffix}`
}
//随机生成字母
exports.generateRandomLowerCaseString = (length) => {
  let result = '';
  const characters = 'abcdefghijklmnopqrstuvwxyz';
  const charactersLength = characters.length;
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}
/**生成随机整数字符串*/
exports.generateRandomIntegerLenght = (length) => {
  const min = Math.pow(10, length - 1);
  const max = Math.pow(10, length) - 1;
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
exports.generateUniqueString = () => {
  // 使用uuid库生成一个v4版本的UUID  
  return uuidv4();
}
exports.randomDate = (startDate, endDate) => {
  // 将开始时间和结束时间转换为时间戳
  const startTimestamp = new Date(startDate).getTime()
  const endTimestamp = new Date(endDate).getTime()
  // 在时间范围内生成随机的时间戳
  const randomTimestamp = startTimestamp + Math.random() * (endTimestamp - startTimestamp)
  // 将随机的时间戳转换为日期对象
  return new Date(randomTimestamp)
}
/**
 * 
 * @returns 返回随机手机号
 */
exports.generateRandomPhoneNumber = () => {
  var prefix = [13, 14, 15, 16, 17, 18, 19]; // 手机号码前缀  
  var phone = '';
  // 随机选择一个前缀  
  var randomPrefix = prefix[Math.floor(Math.random() * prefix.length)];
  phone += randomPrefix;
  // 生成后8位随机数  
  for (var i = 0; i < 8; i++) {
    phone += Math.floor(Math.random() * 10);
  }
  return phone;
}
/**
 * 
 * @param {String} prefix 前缀
 * @param {Number} startNumber 开始数字
 * @param {Number} endNumber 结束数字
 * @returns 数组
 */
exports.generateSerialNumbers = (prefix, startNumber, endNumber) => {
  // const prefix = 'LMC';  
  // const startNumber = 1;  
  // const endNumber = 100;  
  const serialNumbers = [];
  for (let i = startNumber; i <= endNumber; i++) {
    // 格式化数字，确保是三位数，不足部分用0填充  
    const formattedNumber = i.toString().padStart(3, '0');
    const serialNumber = prefix + formattedNumber;
    serialNumbers.push(serialNumber);
  }
  return serialNumbers;
}
exports.getDate = (utcTimeString) => {
  const date = new Date(utcTimeString);
  // 获取UTC时间的各个部分  
  const utcYear = date.getUTCFullYear();
  const utcMonth = date.getUTCMonth() + 1; // 月份是从0开始的，所以需要加1  
  const utcDate = date.getUTCDate();
  const utcHours = date.getUTCHours();
  const utcMinutes = date.getUTCMinutes();
  const utcSeconds = date.getUTCSeconds();
  const utcMilliseconds = date.getUTCMilliseconds();
  // 格式化UTC时间  
  const utcFormattedTime = `${utcYear}-${utcMonth.toString().length == 1 ? '0' + utcMonth : utcMonth}-${utcDate.toString().length == 1 ? '0' + utcDate : utcDate} ${utcHours.toString().length == 1 ? '0' + utcHours : utcHours}:${utcMinutes.toString().length == 1 ? '0' + utcMinutes : utcMinutes}:${utcSeconds.toString().length == 1 ? '0' + utcSeconds : utcSeconds}`
  // console.log(utcMonth.toString().length)
  return utcFormattedTime
}
exports.randomUpperCase = (str) => {
  // 移除短横线  
  let noDashStr = str.replace(/-/g, '');
  // 创建一个数组来存储每个字符  
  let charArray = noDashStr.split('');
  // 随机选择部分字符转换为大写  
  for (let i = 0; i < charArray.length; i++) {
    if (Math.random() < 0.5) { // 50% 的概率转换为大写  
      charArray[i] = charArray[i].toUpperCase();
    }
  }
  // 将数组重新组合为字符串  
  return charArray.join('');
}
exports.hideUrl = (url) => {
  let getUrlArry = url.split('.')
  let NeedHideStr = getUrlArry[getUrlArry.length - 2]
  NeedHideStr = NeedHideStr.slice(NeedHideStr.length - 6)
  let hideUrl = url.replace(NeedHideStr, '******')
  return hideUrl
}
/**
 * 
 * @param {Object} probabilities 
 * @returns 
 */
exports.getRandomRisk = (probabilities) => {
  // // 定义各个风险等级的概率  
  // const probabilities = {  
  //     '暂未开通': 0.1, // 10%  
  //     '风险低': 0.8,   // 80%  
  //     '危险驾驶风险高': 0.01, // 1%  
  //     '危险驾驶风险中': 0.04, // 4%  
  //     '疲劳驾驶风险高': 0.01, // 1%  
  //     '疲劳驾驶风险中': 0.04, // 4%  
  // };  
  let sum = 0;
  let result;
  // 生成一个0到1之间的随机数  
  const random = Math.random();
  // 遍历概率对象，累加概率，直到超过随机数  
  for (const risk in probabilities) {
    sum += probabilities[risk];
    if (random < sum) {
      result = risk;
      break;
    }
  }
  return result;
}
exports.getRandomItems = (options, minCount, maxCount) => {
  // 确保minCount和maxCount在有效范围内  
  minCount = Math.max(1, minCount);
  maxCount = Math.min(options.length, maxCount);
  // 创建一个结果数组  
  let result = [];
  // 循环抽取指定数量的项  
  for (let i = 0; i < Math.floor(Math.random() * (maxCount - minCount + 1)) + minCount; i++) {
    // 从选项中随机选择一个项  
    let index = Math.floor(Math.random() * options.length);
    // 如果该项尚未被选中，则添加到结果数组中  
    if (!result.includes(options[index])) {
      result.push(options[index]);
    } else {
      // 如果该项已被选中，则重试  
      i--;
    }
  }
  return result;
}
/**
 * @param { String } str 例如:"2024-4-15"
 * @returns 返回前七天数组
 */
exports.getNew7Day = (str) => {
  // 假设你有一个特定的日期
  let specificDate = str ? new Date(str) : new Date() ; // 例如：2023年6月20日 
  // 初始化一个数组来存储日期  
  let dates = [];
  // 循环获取前七天的日期  
  for (let i = 0; i <= 7; i++) {
    dates.unshift(new Date(specificDate.getTime() - (i * 24 * 60 * 60 * 1000)));
  }
  // 格式化日期数组  
  return dates.map(date => {
    let day = date.getDate();
    let month = date.getMonth() + 1; // 月份是从0开始的，所以需要加1  
    let year = date.getFullYear();
    day = day < 10 ? '0' + day : day;
    month = month < 10 ? '0' + month : month;
    return year + '-' + month + '-' + day;
  });

}
/**
 * 
 * @param {Date} startDate 
 * @param {Date} endDate 
 * @returns 返回两个日期的天数数组
 */
 exports.getDatesBetween = (startDate, endDate) => {  
  let dateArray = [];  
  let currentDate = new Date(startDate);  
  let currentEndDate = new Date(endDate);  
  if((!currentDate) || (!currentEndDate) ){
    throw Error()
  }
  while (currentDate <= currentEndDate) {  
      dateArray.push(this.convertUtcToChinaTime(new Date(currentDate)));  
      currentDate.setDate(currentDate.getDate() + 1);  
  }  
  return dateArray;  
} 
exports.convertUtcToChinaTime = (utcDateStr)=>{  
  // 创建UTC时间的Date对象  
  let utcDate = new Date(utcDateStr); // 注意：这里加上了'Z'来表示UTC时间  
  // 计算中国时间的毫秒数（东八区，加8小时）  
  let chinaTimeMilliseconds = utcDate.getTime() + (8 * 60 * 60 * 1000);  
  // 创建中国时间的Date对象  
  let chinaTime = new Date(chinaTimeMilliseconds);  
  // 提取年、月、日  
  let year = chinaTime.getFullYear();  
  let month = chinaTime.getMonth() + 1; // getMonth()返回的月份是从0开始的，所以需要加1  
  let day = chinaTime.getDate();  
  // 如果月份或日期小于10，则在前面补0  
  month = month < 10 ? '0' + month : month;  
  day = day < 10 ? '0' + day : day;  
  // 拼接年月日字符串  
  let chinaTimeStr = year + '-' + month + '-' + day;  
  return chinaTimeStr;  
}  
exports.getRandomDateBetween = (startDate, endDate) => {
  // 将两个日期转换为毫秒数  
  const start = new Date(startDate).getTime();
  const end_tmp = new Date(endDate);
  const end = new Date(end_tmp.getFullYear(), end_tmp.getMonth() , end_tmp.getDate(), 23, 59, 59);
  // 生成一个介于两个日期之间的随机毫秒数  
  const randomMillis = Math.random() * (end - start) + start;
  // 将随机毫秒数转换回Date对象  
  const randomDate = new Date(randomMillis);
  // 确保随机日期不包括endDate（如果需要的话）  
  if (randomDate >= endDate) {
      return new Date(end - 1); // 减去1毫秒以确保不包括endDate本身  
  }
  return randomDate;

} 